<?php

namespace Once\Orm;
use Once\Api;

/**
 * Created by PhpStorm.
 * User: caoyangmin
 * Date: 16/11/15
 * Time: 下午8:53
 */
class Model extends \Illuminate\Database\Eloquent\Model
{
    /**
     * Model constructor.
     * @param string|object $entity
     */
    static function createByEntity($entity, $exist){

        $filldata =[];
        $fillable = [];
        if (is_string($entity)){
            $entityClass = $entity;
        }elseif(is_object($entity)){
            $entityClass = get_class($entity);
            //TODO 嵌套entity
            $filldata = get_object_vars($entity);
        }

        $container = Api::getInstance()->getEntity($entityClass);

        $tableName = $container->getClassAnnotationFirst('o-table');
        if(!$tableName){
            $tableName = self::classToTableName($entityClass);
        }else{
            $tableName = $tableName[0];
        }

        foreach ($container->getProperties() as $property){
            $fillable[] = $property->name;// TODO * 支持映射
        }

        $model = new static;
        $model->setTable($tableName);
        $model->fillable($fillable);
        $model->fill($filldata);
        $model->container = $container;
        $model->exists = $exist;
        if(is_object($entity)){
            $model->refEntity = $entity;
        }
        return $model;
    }
    public function __construct(array $attributes=[])
    {
        parent::__construct($attributes);
    }

    /**
     * Create a new Eloquent query builder for the model.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder|static
     */
    public function newEloquentBuilder($query)
    {
        $builder = new Builder($query);
        return $builder;
    }

    /**
     * Create a new instance of the given model.
     *
     * @param  array  $attributes
     * @param  bool  $exists
     * @return static
     */
    public function newInstance($attributes = [], $exists = false)
    {
        // This method just provides a convenient way for us to generate fresh model
        // instances of this current model. It is particularly useful during the
        // hydration of new objects via the Eloquent query builder instances.
        $model = new static((array) $attributes);

        $model->setTable($this->getTable());
        $model->fillable($this->getFillable());
        $model->setEntityContainer($this->getEntityContainer());

        $model->exists = $exists;

        return $model;
    }

    private static function classToTableName($className){
        //去掉namespace
        $names = explode('\\',$className);
        $table = $names[count($names)-1];
        //全小写
        return strtolower($table);
    }

    //work with IDE
    public function increment($column, $amount = 1, array $extra = [])
    {
        return parent::increment($column, $amount, $extra);
    }
    public function decrement($column, $amount = 1, array $extra = [])
    {
        return parent::decrement($column, $amount, $extra);
    }
    /**
     * Find a model by its primary key.
     *
     * @param  mixed  $id
     * @param  array  $columns
     * @return Model|Model[]|null
     */
    public function find($id, $columns = ['*'])
    {
        return call_user_func_array(['parent',__FUNCTION__], func_get_args());
    }

    public function findEntity($id)
    {
        $model = $this->find($id);
        if(!$model){
            return null;
        }
        return $this->container->make(app(), $model->getAttributes());
    }


    /**
     * Find multiple models by their primary keys.
     *
     * @param  array  $ids
     * @param  array  $columns
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function findMany($ids, $columns = ['*'])
    {
        return call_user_func_array(['parent',__FUNCTION__], func_get_args());
    }

    /**
     * Add a basic where clause to the query.
     *
     * @param  string  $column
     * @param  string  $operator
     * @param  mixed   $value
     * @param  string  $boolean
     * @return Builder
     */
    public function where($column, $operator = null, $value = null, $boolean = 'and')
    {
        return call_user_func_array(['parent',__FUNCTION__], func_get_args());
    }

    /**
     * @return \Once\Container\EntityContainer
     */
    public function getEntityContainer()
    {
        return $this->container;
    }

    /**
     * @param \Once\Container\EntityContainer $container
     */
    public function setEntityContainer($container)
    {
        $this->container = $container;
    }

    /**
     * 返回实体
     * @return mixed
     */
    public function entity(){
        return $this->container->make(app(), $this->getAttributes());
    }

    /**
     * Save the model to the database.
     *
     * @param  array  $options
     * @return bool
     */
    public function save(array $options = [])
    {
        $saved = parent::save($options);
        if($saved && $this->refEntity){
            foreach ($this->attributes as $k => $v){
                $this->refEntity->{$k} = $v;
            }
        }
        return $saved;
    }
    /**
     * @var \Once\Container\EntityContainer
     */
    protected $container;


    protected $refEntity;
    //TODO * 通过注释指定incrementing\timestamps \primaryKey等
    public $timestamps = false;
}

